<template>
  <div class="ai-assistant-container">
    <!-- AI 助手标题栏 -->
    <div class="ai-header">
      <span>AI分析助手</span>
      <!-- <div class="header-actions">
        <el-radio-group v-model="activeMode" size="small">
          <el-radio-button label="chat" size="small">对话模式</el-radio-button>
          <el-radio-button label="analysis" size="small">智能推荐</el-radio-button>
        </el-radio-group>
        <el-button type="primary" size="small" @click="refreshAnalysis">刷新分析</el-button>
      </div> -->
    </div>

    <!-- 主内容区域 -->
    <div class="main-content">
      <!-- 聊天区域 -->
      <div v-show="activeMode === 'chat'" class="chat-section">
        <div class="chat-messages" ref="chatRef">
          <Flex gap="middle" vertical>
            <Bubble>
              <template #message>
                <span class="message-content">欢迎使用智能助手，你可以向我提问任何问题，例如：</span>
                <span class="message-content">
                  <ol>
                    <li>
                      <a href="javascript:void(0)" @click="() => (userInput = '请对比一下清华大学和北京大学')">
                        请对比一下清华大学和北京大学
                      </a>
                    </li>
                    <li>
                      <a
                        href="javascript:void(0)"
                        @click="() => (userInput = '我的高考分数是560，目标专业软件工程，请给我推荐合适的院校')"
                      >
                        我的高考分数是560，目标专业软件工程，请给我推荐合适的院校
                      </a>
                    </li>
                  </ol>
                </span>
              </template>
            </Bubble>
            <Bubble
              v-for="(msg, index) in messages"
              :key="index"
              :placement="msg.role === 'user' ? 'end' : 'start'"
              :avatar="{ icon: h(UserOutlined), style: msg.role === 'user' ? barAvatar : fooAvatar }"
            >
              <template #message>
                <div v-if="isAsking && index === messages.length - 1" class="typing-indicator">
                  <span class="dot"></span>
                  <span class="dot"></span>
                  <span class="dot"></span>
                </div>
                <span v-else class="message-content" v-html="md.render(msg.displayContent || msg.content)"></span>
              </template>
            </Bubble>
          </Flex>
        </div>

        <div class="chat-input-wrapper">
          <div class="input-actions">
            <Sender
              placeholder="请输入问题"
              v-model:value="userInput"
              @submit="senderSubmit"
              :loading="isTyping || isAsking"
              :readOnly="isAsking"
              @cancel="stopTyping"
            ></Sender>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, onMounted, ref, watch, onUnmounted, nextTick } from "vue"
import { getAiChatApi } from "@/interface/chat-ai"
import MarkdownIt from "markdown-it"
import hljs from "highlight.js"

import "highlight.js/styles/atom-one-dark.css"
import "highlight.js/lib/common"

import { Bubble, Sender } from "ant-design-x-vue"
import { UserOutlined } from "@ant-design/icons-vue"
import { Flex, Avatar } from "ant-design-vue"
import type { CSSProperties } from "vue"
import { h } from "vue"

defineOptions({ name: "AXBubbleAvatarAndPlacementSetup" })

// 分析助手头像
const fooAvatar: CSSProperties = {
  color: "#f56a00",
  backgroundColor: "#fde3cf"
}

// 用户头像
const barAvatar: CSSProperties = {
  color: "#fff",
  backgroundColor: "#87d068"
}

interface Props {
  provinces: string[]
  schools: string[]
}
const props = withDefaults(defineProps<Props>(), {})
const emits = defineEmits<{
  (e: "update:schools", val: string[]): void
  (e: "update:provinces", val: string[]): void
}>()

// 对大模型的对话进行封装渲染
const md = new MarkdownIt({
  highlight: function (str, lang) {
    if (lang && hljs.getLanguage(lang)) {
      try {
        // 使用新的 highlight 方法
        return '<pre class="hljs"><code>' + hljs.highlight(str, { language: lang }).value + "</code></pre>"
      } catch (__) {
        // 出错时使用默认处理
      }
    }
    return '<pre class="hljs"><code>' + MarkdownIt().utils.escapeHtml(str) + "</code></pre>"
  }
})
const activeMode = ref("chat")
const userInput = ref("")
const messages = ref<
  {
    role: string
    content: string
    displayContent?: string
  }[]
>([])
const chatRef = ref<HTMLElement | null>(null)
const isTyping = ref(false) // 是否正在打字
const isAsking = ref(false) // 是否正在提问
const typingController = ref<AbortController | null>(null)
const typingInterval = ref<number | null>(null)
const controller = ref<any>(null)

// 监听消息变化，自动滚动到底部
watch(
  messages,
  () => {
    nextTick(() => {
      scrollToBottom()
    })
  },
  {
    deep: true
  }
)

// 滚动到底部
const scrollToBottom = () => {
  if (chatRef.value) {
    chatRef.value.scrollTop = chatRef.value.scrollHeight
  }
}

// 打字机效果
const typewriterEffect = (text: string, messageIndex: number) => {
  let currentIndex = 0
  const message = messages.value[messageIndex]

  // 确保displayContent存在
  if (!message.displayContent) {
    message.displayContent = ""
  }

  // 清除之前的定时器
  if (typingInterval.value) {
    clearInterval(typingInterval.value)
  }

  isTyping.value = true

  // 设置打字机效果
  typingInterval.value = window.setInterval(() => {
    if (currentIndex < text.length) {
      message.displayContent = text.substring(0, currentIndex + 1)
      currentIndex++
      scrollToBottom()
    } else {
      // 打字完成
      if (typingInterval.value) {
        clearInterval(typingInterval.value)
        typingInterval.value = null
      }
      isTyping.value = false
    }
  }, 30) // 打字速度，可以调整
}

// 停止打字机效果
const stopTyping = () => {
  if (isAsking.value) {
    controller.value && controller.value.abort()
    return
  }

  if (typingInterval.value) {
    clearInterval(typingInterval.value)
    typingInterval.value = null
  }

  // 显示完整内容
  const lastMessage = messages.value[messages.value.length - 1]
  if (lastMessage && lastMessage.role === "assistant") {
    lastMessage.displayContent = lastMessage.content
  }

  // 终止API请求
  if (typingController.value) {
    typingController.value.abort()
    typingController.value = null
  }

  isTyping.value = false
}

const senderSubmit = () => {
  if (!userInput.value.trim() || isTyping.value) return

  messages.value.push({
    role: "user",
    content: userInput.value
  })

  // 添加AI消息占位
  messages.value.push({
    role: "assistant",
    content: "",
    displayContent: ""
  })

  // 准备消息历史
  const messageHistory = messages.value.slice(0, -1).map(msg => ({
    role: msg.role,
    content: msg.content
  }))

  // 设置打字状态
  isAsking.value = true

  // 创建新的AbortController
  typingController.value = new AbortController()

  // 调用AI接口
  controller.value = getAiChatApi(messageHistory, (data, isDone) => {
    console.log("data:", data)
    console.log("isDone:", isDone)
    if (isDone) {
      isAsking.value = false
      return
    }

    console.log("data:", data)

    // 处理不同类型的消息
    if (data.type === "message") {
      // 更新AI回复
      const messageIndex = messages.value.length - 1
      messages.value[messageIndex].content = data.content

      // 应用打字机效果
      typewriterEffect(data.content, messageIndex)
    } else if (data.type === "recommendations-schools") {
      // 处理大学院校推荐
      console.log("recommendations-schools:", data.content)
      try {
        const recommendations = JSON.parse(data.content)
        console.log("recommendations-schools:", recommendations)
        if (recommendations && Array.isArray(recommendations)) {
          schools.value = recommendations
        }
      } catch (error) {
        console.error("解析推荐学校数据失败:", error)
      }
    } else if (data.type === "recommendations-provinces") {
      // 处理大学院校推荐省份
      console.log("recommendations-provinces:", data.content)
      try {
        const recommendations = JSON.parse(data.content)
        console.log("recommendations:", recommendations)
        if (recommendations && Array.isArray(recommendations)) {
          provinces.value = recommendations
        }
      } catch (error) {
        console.error("解析推荐省份数据失败:", error)
      }
    } else if (data.type === "error") {
      // 处理错误
      const messageIndex = messages.value.length - 1
      messages.value[messageIndex].content = `发生错误: ${data.content}`
      messages.value[messageIndex].displayContent = `发生错误: ${data.content}`
      isTyping.value = false

      console.log("isTyping:", isTyping.value)
    }
  })

  // 清空输入框
  userInput.value = ""

  // 组件卸载时取消请求
  onUnmounted(() => {
    if (controller.value) {
      controller.value.abort()
    }
    if (typingInterval.value) {
      clearInterval(typingInterval.value)
    }
  })
}

const schools = computed({
  get: () => props.schools,
  set: val => {
    emits("update:schools", val)
    scrollToBottom()
  }
})

const provinces = computed({
  get: () => props.provinces,
  set: val => {
    emits("update:provinces", val)
    scrollToBottom()
  }
})

onMounted(() => {
  scrollToBottom()
})
</script>

<style lang="scss" scoped>
.ai-assistant-container {
  height: 100%;
  display: flex;
  flex-direction: column;

  .ai-header {
    @include flex-between;
    margin-bottom: 15px;
    padding-bottom: 15px;
    border-bottom: 1px solid var(--border-color);

    .header-actions {
      display: flex;
      gap: 10px;
      align-items: center;
    }
  }

  .main-content {
    flex: 1;
    min-height: 0;

    .chat-section {
      height: 100%;
      display: flex;
      flex-direction: column;
      overflow: hidden;

      .chat-messages {
        flex: 1;
        overflow-y: auto;
        overflow-x: hidden;
        padding: 10px;
        @include custom-scrollbar;
      }

      .chat-input-wrapper {
        margin-top: 15px;
        padding: 10px;
        background-color: var(--background-color-base);
        border-radius: 8px;

        .input-actions {
          display: flex;
          gap: 10px;
          align-items: center;

          .stop-button {
            flex-shrink: 0;
          }
        }
      }
    }
  }
}

.message-content {
  max-width: 100%;
  word-wrap: break-word;
  overflow-wrap: break-word;

  /* 控制代码块容器的样式 */
  :deep(.hljs) {
    max-width: 100%;
    overflow-x: auto;
    white-space: pre;
    padding: 1em;
    border-radius: 4px;
  }

  /* 确保代码内容不会撑开容器 */
  :deep(.hljs code) {
    white-space: pre-wrap;
    word-break: break-word;
  }

  :first-child {
    margin-top: 0;
  }
  :last-child {
    margin-bottom: 0;
  }
}

/* 大学院校推荐样式 */
.recommendations-container {
  margin: 20px 0;
  padding: 16px;
  background-color: #f9f9f9;
  border-radius: 8px;
  border: 1px solid #eee;
}

.recommendations-container h3 {
  margin-top: 0;
  margin-bottom: 12px;
  color: #333;
  font-size: 16px;
}

.schools-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.school-item {
  padding: 12px;
  background-color: #fff;
  border-radius: 6px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

.school-name {
  font-weight: bold;
  margin-bottom: 4px;
  color: #1890ff;
}

.school-reason {
  font-size: 14px;
  color: #666;
}

.typing-indicator {
  display: flex;
  gap: 4px;
  padding: 8px 0;
  justify-content: center;

  .dot {
    width: 8px;
    height: 8px;
    background-color: #909399;
    border-radius: 50%;
    animation: typing 1s infinite ease-in-out;

    &:nth-child(2) {
      animation-delay: 0.2s;
    }

    &:nth-child(3) {
      animation-delay: 0.4s;
    }
  }
}

@keyframes typing {
  0%,
  100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-5px);
  }
}
</style>
